
#ifndef _MEMBER_BHTMLITEM_H_
#define _MEMBER_BHTMLITEM_H_

#include <BMap>
#include <BXmlNode>
#include <BHtmlItem>
#include <BHtmlWidget>
#include "ICodeCell.h"
#include "IHtmlStyle.h"
#include "IRound.h"

#define item_member(item)			((member_BHtmlItem*)((BHtmlItem*)item)->_ptr)

namespace BWE
{
	class member_BHtmlItem
	{
		friend class BHtmlItem;
	public:
		member_BHtmlItem(BHtmlItem* htmlItem);
		~member_BHtmlItem();

		void attach(BHtmlWidget* htmlWidget);
		void detach(BHtmlWidget* htmlWidget);

		void dirtyHtml();
		void resetStyle();
		void applyStyle(const BFont* upperFont);
		void applyRoundStyle();

		BHtmlItem* upperBlock();
		IHtmlStyle* baseStyle();
		const BFont* baseFont();

		BSize freshBlock(const BPoint& point, int page);
		BSize freshInlineBlock(const BPoint& point, int page);
		void freshInline(BRect& cursor, int left, int page);
		void linefeed(BRect& cursor);
		void fresh_table(BRect& cursor, int page);
		void fresh_ulist(BRect& cursor, int page);
		void fresh_olist(BRect& cursor, int page);
		void fresh_dlist(BRect& cursor, int page);
		void fresh_image(BRect& cursor, int page);

		void moveArea(const BPoint& offset);
		void adjustRects();
		void adjustBorder();
		void adjustFloat();

		void paint(BPainter& painter, const BPoint& offset);
		void paint_ulist(BPainter& painter, const BPoint& offset);
		void paint_olist(BPainter& painter, const BPoint& offset);
		void paint_dlist(BPainter& painter, const BPoint& offset);
		void paint_image(BPainter& painter, const BPoint& offset);

		typedef void (member_BHtmlItem::* func_fresh)(BRect& cursor, int width);
		typedef void (member_BHtmlItem::* func_paint)(BPainter& painter, const BPoint& offset);

	public:
		inline bool empty() const
		{
			return cells.empty();
		}
		inline bool valid() const
		{
			return cells.size();
		}
		inline int tail() const
		{
			if (cells.last().code == '\n')
				return cells.size() - 1;
			return cells.size();
		}

		void flushText();
		void resetCells();

		void append(const BString& text);
		bool remove(int pos, int count = 1);
		bool insert(const BCode& code);
		bool insert(const BString& text);

		void substr(BString& str, int pos, int count) const;
		void selection(BString& str) const;

		bool selectWord();
		bool removeSelection();

		bool seekHead();
		bool seekPoint(const BPoint& point);
		bool seekTail();

		int seekPrevCode();
		int seekNextCode();
		int seekPrevWord();
		int seekNextWord();

		int indexAt(const BPoint& pos) const;
		int wordWidth(int index) const;

		void adjustText(BRect& cursor, int left, int page);
		void paintText(const BRect& clip, const BPoint& offset);

	public:
		BHtmlItem*				boss;
		BHtmlWidget*			html;
		bool					selected;
		BString					position;
		BSizef					sizeRatio;
		BSize					fixedSize;
		BSize					minSize;
		BSize					maxSize;
		Align					floatAlign;
		BMargin					margin;
		BMargin					border;
		BMargin					padding;
		BHtmlItem::Display		display;
		BStringArray			classes;
		BHolder<IHtmlStyle>		realStyle;
		func_fresh				freshFunc;
		func_paint				paintFunc;

		bool					dirty;
		bool					dirtyStyle;
		bool					wordWrap;
		Align					textAlign;
		int						inputIndex;
		int						inputCount;
		BHolder<BFont>			font;
		BHolder<const BFont>	realFont;
		int						spacing;
		float					lineHeight;
		BRect					area;
		BRect					rect;
		BRect					client;
		BRect					textRect;
		BSize					sizeHint;
		BRect					rectLeft;
		BRect					rectTop;
		BRect					rectRight;
		BRect					rectBottom;
		BHolder<IRound>			round;
		BArray<ICodeCell>		cells;

		BColor					background;
		BImageHolder			backgroundImage;
		BImageHolder			listStyleImage;
		BHtmlItem::Style		listStyle;
		Orientation				flexDirection;
		BColor					textColor;
		BColor					borderLeftColor;
		BColor					borderTopColor;
		BColor					borderRightColor;
		BColor					borderBottomColor;
		BImageHolder			image;
	};
}

#endif
